# set options
options(stringsAsFactors = F) # no automatic data transformation
options("scipen" = 100, "digits" = 4) # suppress math annotation
# install packages
install.packages("tidyverse")
install.packages("flextable")
install.packages("leaflet")
How to create a typological map in R with leaflet
Introduction
This document represents an empty R Quarto file (or qmd file) for a LADAL tutorial. The R Quarto document for this tutorial can be downloaded here.
You will also have to download the bibliography file from https://slcladal.github.io/content/references.bib for the tutorial to be knitted correctly. Although the knitted (or rendered) html file will look different from the LADAL design (because we have modified the theme for the LADAL page), it will be just like a proper LADAL tutorial once we have knitted the Rmd file on our machines and integrated your tutorial into the LADAL website.
The entire R Notebook for the tutorial can be downloaded here. If you want to render the R Notebook on your machine, i.e. knitting the document to html or a pdf, you need to make sure that you have R and RStudio installed and you also need to download the bibliography file and store it in the same folder where you store the Rmd or the Rproj file.
Preparation and session set up
This tutorial is based on R. If you have not installed R or are new to it, you will find an introduction to and more information how to use R here. For this tutorials, we need to install certain packages from an R library so that the scripts shown below are executed without errors. Before turning to the code below, please install the packages by running the code below this paragraph. If you have already installed the packages mentioned below, then you can skip ahead and ignore this section. To install the necessary packages, simply run the following code - it may take some time (between 1 and 5 minutes to install all of the libraries so you do not need to worry if it takes some time).
Next, we activate the packages.
library(tidyverse)
library(flextable)
library(leaflet)
Once you have installed R, RStudio, and have also initiated the session by executing the code shown above, you are good to go.
Typological data
The objective of this tutorial is to use R to create a typological map as in the World Atlas of Linguistic Structures (WALS)(Dryer and Haspelmath 2013). The WALS is a large database that documents the structural features of languages around the world. It provides information on a wide range of linguistic characteristics, from phonological traits to grammatical structures. A typical WALS dataset includes information about various languages and specific linguistic features. Each row in the dataset represents a single language, and the columns contain metadata about the language and data about its structural features.
For instance, Comrie (1998) contains typological information about the “Order of Subject and Verb”, with three levels: “SV”, “VS”, and “No dominant order”. The related typological map can be found here.
To create a typological map, you need a dataset with four variables/columns, as illustrated in Table 1:
<- data.frame(
data Language = c("Tiranige", "Amharic", "Hungarian", "Vietnamese", "Indonesian", "..."),
Longitude = c(3.70, 39.54, 19.66, 105.77, 109.72, NA),
Latitude = c(14.76, 11.71, 46.91, 20.68, -7.33, NA),
Feature = c("absent", "other", "absent", "absent", "other", "...")
)
<- flextable(data) |> set_header_labels(
ft Language = "Language",
Longitude = "Longitude",
Latitude = "Latitude",
Feature = "Feature"
|>
) set_table_properties(width = .5, layout = "autofit") |>
theme_zebra() |>
fontsize(size = 12) |>
fontsize(size = 12, part = "header") |>
align_text_col(align = "center") |>
border_outer()
ft
Language | Longitude | Latitude | Feature |
---|---|---|---|
Tiranige | 3.70 | 14.76 | absent |
Amharic | 39.54 | 11.71 | other |
Hungarian | 19.66 | 46.91 | absent |
Vietnamese | 105.77 | 20.68 | absent |
Indonesian | 109.72 | -7.33 | other |
... | ... |
The dataset should contain a column/variable with the languages, two columns/variables with the geographical coordinates for each language, i.e., Longitude and Latitude (in decimal numbers, not degrees!), and a columns/variable with the typological feature under analysis.
A mock dataset
Here we create a mock dataset with twenty languages (rows), their geographical coordinates and one hypothetical Feature
with three levels: “present”, “absent” and “other”.
<- c("Tiranige", "Amharic", "Hungarian", "Vietnamese", "Indonesian",
Language "Kalaallisut (West Greenlandic)", "Magdalena Peñasco Mixtec", "Cayuga",
"Laz", "Japanese", "Buwal", "Yucatec Maya", "Manx", "Forest Enets",
"Lopit", "Mojeño Trinitario", "Ulwa (Yaul)", "Japhug",
"West Circassian", "Kuuk Thayorre")
<- c(-3.70, 39.54, 19.66, 105.77, 109.72, -52.86, -97.54, -76.60,
Longitude 41.91, 135.00, 10.62, -88.96, -4.45, 86.50, 32.75, -65.41,
143.99, 102.36, 39.33, 142.03)
<- c(14.76, 11.71, 46.91, 20.68, -7.33, 69.38, 17.28, 42.41,
Latitude 41.50, 35.00, 13.88, 18.78, 54.26, 68.60, 4.70, -15.33,
-4.40, 32.10, 44.00, -14.82)
<- c("absent", "other", "absent", "absent", "other", "absent", "absent",
Feature "present", "other", "absent", "present", "present", "present",
"present", "present", "absent", "other", "present", "present", "present")
<- data.frame(Language, Longitude, Latitude, Feature)
typ $Feature <- as.factor(typ$Feature) typ
Check the first rows:
head(typ) |>
flextable() |>
::set_table_properties(width = .5, layout = "autofit") |>
flextable::theme_zebra() |>
flextable::fontsize(size = 12) |>
flextable::fontsize(size = 12, part = "header") |>
flextable::align_text_col(align = "center") |>
flextable::set_caption(caption = "") |>
flextable::border_outer() flextable
Language | Longitude | Latitude | Feature |
---|---|---|---|
Tiranige | -3.70 | 14.76 | absent |
Amharic | 39.54 | 11.71 | other |
Hungarian | 19.66 | 46.91 | absent |
Vietnamese | 105.77 | 20.68 | absent |
Indonesian | 109.72 | -7.33 | other |
Kalaallisut (West Greenlandic) | -52.86 | 69.38 | absent |
Create map
First, we define a WALS-like colour palette (other colour palettes can be used):
<- c("#0000dd", # colour for "present"
col "#dd0000", # colour for "absent"
"#ff66ff") # colour for "other"
# at this stage the colours are not yet assigned to the levels of Feature!
We use leaflet::colorFactor
to map the colour palette to the levels of the variable Feature
.
<- colorFactor(palette = col,
color_pal_WALS levels = c("present", "absent", "other"))
We are now ready to create a leaflet map.
1leaflet(typ) |>
2addTiles() |>
3addCircleMarkers(
~Longitude, ~Latitude,
fillColor = ~color_pal_WALS(Feature),
color = "white",
radius = 8,
fillOpacity = 1,
stroke = TRUE,
weight = 1,
label = ~Language,
popup = ~paste("<strong>Language:</strong>", Language,
"<br><strong>Coexpression:</strong>", Feature)
|>
) 4addLegend("topright",
pal = color_pal_WALS,
values = ~Feature,
title = "Feature",
opacity = 0.9)
- 1
- create a leaflet object
- 2
- add Open streetmap tile
- 3
-
Set option for the visualisation of the markers (points) on the map. We set the following options:
~Longitude, ~Latitude
: based on the coordinate variables in the dataset,fillColor
: apply the defined color palette,color
the color of the border of the circles,radius:
changes the width of the circles,fillOpacity
: changes the opacity, with 1 removing the transparency completely,stroke = TRUE
: adds a circle around the circles,weight
: the width of the circles,label = ~Language
: adds the languages as labels to the circles on the map, which appear when hovering over the circles,popup
: what appears when hovering over the circles. - 4
- Adds a legend on the upper left corner, with the correct labels (languages) and specified colours.
Citation & Session Info
De Cuypere, Ludovic. 2025. How to Create a typological map in R with leaflet. Vrije Universiteit Brussel, Ghent University. url: https://slcladal.github.io/TypologicalmapsinR.html (Version 2025.03.26).
@manual{DeCuypere2025net,
author = {De Cuypere, Ludovic},
title = {How to Create a typological map in R with leaflet},
note = {https://slcladal.github.io/TypologicalmapsinR.html},
year = {2025},
organization = {Vrije Universiteit Brussel & Ghent University},
address = {Pleinlaan 2, 1050 Brussel (Elsene)},
edition = {2025.03.26}
}
sessionInfo()
R version 4.4.2 (2024-10-31 ucrt)
Platform: x86_64-w64-mingw32/x64
Running under: Windows 11 x64 (build 26100)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.utf8
[2] LC_CTYPE=English_United States.utf8
[3] LC_MONETARY=English_United States.utf8
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.utf8
time zone: Australia/Brisbane
tzcode source: internal
attached base packages:
[1] stats graphics grDevices datasets utils methods base
other attached packages:
[1] leaflet_2.2.2 flextable_0.9.7 lubridate_1.9.4 forcats_1.0.0
[5] stringr_1.5.1 dplyr_1.1.4 purrr_1.0.4 readr_2.1.5
[9] tidyr_1.3.1 tibble_3.2.1 ggplot2_3.5.1 tidyverse_2.0.0
loaded via a namespace (and not attached):
[1] generics_0.1.3 fontLiberation_0.1.0 renv_1.1.1
[4] xml2_1.3.6 stringi_1.8.4 hms_1.1.3
[7] digest_0.6.37 magrittr_2.0.3 evaluate_1.0.3
[10] grid_4.4.2 timechange_0.3.0 fastmap_1.2.0
[13] jsonlite_1.9.0 zip_2.3.2 crosstalk_1.2.1
[16] scales_1.3.0 fontBitstreamVera_0.1.1 jquerylib_0.1.4
[19] codetools_0.2-20 textshaping_1.0.0 cli_3.6.4
[22] rlang_1.1.5 fontquiver_0.2.1 munsell_0.5.1
[25] withr_3.0.2 yaml_2.3.10 gdtools_0.4.1
[28] tools_4.4.2 officer_0.6.7 uuid_1.2-1
[31] tzdb_0.4.0 colorspace_2.1-1 vctrs_0.6.5
[34] R6_2.6.1 lifecycle_1.0.4 htmlwidgets_1.6.4
[37] ragg_1.3.3 pkgconfig_2.0.3 pillar_1.10.1
[40] gtable_0.3.6 glue_1.8.0 data.table_1.17.0
[43] Rcpp_1.0.14 systemfonts_1.2.1 xfun_0.51
[46] tidyselect_1.2.1 rstudioapi_0.17.1 knitr_1.49
[49] farver_2.1.2 htmltools_0.5.8.1 rmarkdown_2.29
[52] compiler_4.4.2 askpass_1.2.1 openssl_2.3.2